//
//  YGAdRequestHelper.m
//  YGAdRequestHelper
//
//  Created by 许亚光 on 2018/8/7.
//  Copyright © 2018年 xuyagung. All rights reserved.
//

#import "YGAdRequestHelper.h"
#import <objc/runtime.h>

/**
 * 广告请求+操作Block Key
 */
static char kAdCompleteBlockKey;


@interface YGAdRequestHelper ()
<
FBNativeAdDelegate,
FBAdViewDelegate,
//FBNativeBannerAdDelegate,
FBInterstitialAdDelegate,
FBRewardedVideoAdDelegate,

GADBannerViewDelegate,
GADInterstitialDelegate,
GADRewardBasedVideoAdDelegate
>

/**
 * 广告对象库
 */
@property (nonatomic, strong) NSMutableDictionary *adLibraryDictM;

/**
 * 是否禁用广告请求,默认可用
 */
@property (nonatomic, assign) BOOL adEnable;

/**
 * 是否禁用打印,默认不可用
 */
@property (nonatomic, assign) BOOL logEnable;

/**
 * FB广告测试设备
 */
@property (nonatomic, strong) NSArray *deviceHashs;

/**
 * GAD广告测试设备
 */
@property (nonatomic, strong) NSArray *testDevices;

/**
 * 广告事件回调
 */
@property (nonatomic, copy) YGAdActionHandleBlock adActionHandelBlock;

@end

@implementation YGAdRequestHelper


YGAdRequestHelper *_adInstance = nil;
#pragma mark - 获取广告请求单例对象
+ (instancetype)sharedInstance {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _adInstance = [[self alloc] init];
        _adInstance.adEnable = YES;
        _adInstance.logEnable = NO;
    });
    return _adInstance;
}

#pragma mark - 懒加载广告对象存储字典
- (NSMutableDictionary *)adLibraryDictM {
    if (!_adLibraryDictM) {
        _adLibraryDictM = [[NSMutableDictionary alloc] init];
    }
    return _adLibraryDictM;
}

#pragma mark - 移除广告对象
- (void)removeAdObjectWithPlacementID:(NSString *)placementID {
    @synchronized(self.adLibraryDictM){
        [self.adLibraryDictM removeObjectForKey:placementID];
    }
}

#pragma mark - 设置广告是否可用
- (void)setAdEnable:(BOOL)adEnable {
    _adEnable = adEnable;
    if (!adEnable) {
        [self.adLibraryDictM removeAllObjects];
    }
}

#pragma mark - 设置日志打印
- (void)setLogEnable:(BOOL)logEnable {
    _logEnable = logEnable;
}

#pragma mark - FB广告测试设备
- (void)addFBAdTestDevices:(NSArray<NSString *> *)deviceHashs {
    _deviceHashs = deviceHashs;
    if (deviceHashs.count > 0) {
        if (_logEnable) {
            NSLog(@"-->添加FBAd测试设备:%@",deviceHashs);
        }
        [FBAdSettings addTestDevices:deviceHashs];
    }
}

#pragma mark - ADMob广告测试设备
- (void)addGADTestDevices:(NSArray<NSString *> *)testDevices {
    _testDevices = testDevices;
}

#pragma mark - 注册App
- (void)registerGADAppId:(NSString *)appId {
    [GADMobileAds configureWithApplicationID:appId];
}

/**
 * FB 原生广告是否可用,不存在也是不可用
 */
- (BOOL)isFBNativeAdValid:(NSString *)placementID {
    if (!_adEnable) {
        return NO;
    }
    FBNativeAd *nativeAd = self.adLibraryDictM[placementID];
    if (nativeAd && nativeAd.isAdValid) {
        return YES;
    }
    return NO;
}

- (FBNativeAd *)getFBNativeAd:(NSString *)placementID {
    if (!_adEnable) {
        return nil;
    }
    FBNativeAd *nativeAd = self.adLibraryDictM[placementID];
    if (nativeAd && nativeAd.isAdValid) {
        return nativeAd;
    }
    return nil;
}

/**
 * FB 插屏广告是否可用,不存在也是不可用
 */
- (BOOL)isFBInterstitialAdValid:(NSString *)placementID {
    if (!_adEnable) {
        return NO;
    }
    FBInterstitialAd *interstitialAd = self.adLibraryDictM[placementID];
    if (interstitialAd && interstitialAd.isAdValid) {
        return YES;
    }
    return NO;
}

- (FBInterstitialAd *)getFBInterstitialAd:(NSString *)placementID {
    if (!_adEnable) {
        return nil;
    }
    FBInterstitialAd *interstitialAd = self.adLibraryDictM[placementID];
    if (interstitialAd && interstitialAd.isAdValid) {
        return interstitialAd;
    }
    return nil;
}

#pragma mark - 发送事件通知
- (void)postNotificationWithPlacementId:(NSString *)placementId adPlatform:(YGAdPlatform)adPlatform adType:(YGAdType)adType adAction:(YGAdActionType)adAction error:(NSError *)error {
    
    if (self.adActionHandelBlock) {
        self.adActionHandelBlock(placementId, adAction, adType, adPlatform, error);
    }
    
    NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
    [userInfo setObject:placementId forKey:@"placementId"];
    [userInfo setObject:@(adType) forKey:@"adType"];
    [userInfo setObject:@(adPlatform) forKey:@"adPlatform"];
    [userInfo setObject:@(adAction) forKey:@"actionType"];
    if (error) {
        [userInfo setObject:@(error.code) forKey:@"errorCode"];
        [userInfo setObject:error.localizedDescription forKey:@"errorMessage"];
    }
    [[NSNotificationCenter defaultCenter] postNotificationName:kYGAdRequestHelperAdActionNotificationName object:nil userInfo:userInfo];
}

- (void)adActionHandle:(YGAdActionHandleBlock)handleBlock {
    self.adActionHandelBlock = handleBlock;
}


#pragma mark - 请求广告
- (void)requestFBNativeAd:(NSString *)placementId complete:(YGFBNativeAdBlock)completeBlcok {
    
    if (!_adEnable) {
        if (_logEnable) {
            NSLog(@"您已经禁用了广告请求!");
        }
        
        if (completeBlcok) {
            completeBlcok(nil, NO, NO, nil);
        }
        
        return;
    }
    
    FBNativeAd *nativeAd = self.adLibraryDictM[placementId];
    if (nativeAd) {
        
        if (completeBlcok) {
            objc_setAssociatedObject(nativeAd, &kAdCompleteBlockKey, completeBlcok, OBJC_ASSOCIATION_COPY_NONATOMIC);
        }
        
        if (nativeAd.isAdValid) {
            if (_logEnable) {
                NSLog(@"-->FBNativeAd广告已就绪,可以直接使用:%@",placementId);
            }
            if (completeBlcok) {
                completeBlcok(nativeAd, YES, NO, nil);
            }
        }
        return;
    }

    
    nativeAd = [[FBNativeAd alloc] initWithPlacementID:placementId];
    objc_setAssociatedObject(nativeAd, &kAdCompleteBlockKey, completeBlcok, OBJC_ASSOCIATION_COPY_NONATOMIC);
    nativeAd.delegate = self;
    @synchronized(self.adLibraryDictM){
        [self.adLibraryDictM setValue:nativeAd forKey:placementId];
    }
    
    if (_logEnable) {
        NSLog(@"-->开始请求FBNativeAd广告:%@",placementId);
    }
    
    [self postNotificationWithPlacementId:placementId adPlatform:YGAdPlatformFacebook adType:YGAdTypeNative adAction:YGAdActionTypeRequest error:nil];
    
    [nativeAd loadAd];
}

- (void)requestFBBannerAd:(NSString *)placementId adViewSize:(FBAdSize)size rootViewController:(UIViewController *)rootViewController complete:(YGFBBannerAdBlock)completeBlcok {
    if (!_adEnable) {
        if (_logEnable) {
            NSLog(@"您已经禁用了广告请求!");
        }
        
        if (completeBlcok) {
            completeBlcok(nil, NO, NO, nil);
        }
        return;
    }
    
    FBAdView *adView = self.adLibraryDictM[placementId];
    if (adView) {
        if (completeBlcok) {
            objc_setAssociatedObject(adView, &kAdCompleteBlockKey, completeBlcok, OBJC_ASSOCIATION_COPY_NONATOMIC);
        }
        
        if (_logEnable) {
            NSLog(@"-->FBBannerAd广告已就绪,可以直接使用:%@",placementId);
        }
        if (completeBlcok) {
            completeBlcok(adView, YES, NO, nil);
        }
        
        return;
    }
    
    adView = [[FBAdView alloc] initWithPlacementID:placementId adSize:size rootViewController:rootViewController];
    objc_setAssociatedObject(adView, &kAdCompleteBlockKey, completeBlcok, OBJC_ASSOCIATION_COPY_NONATOMIC);
    adView.delegate = self;
    @synchronized(self.adLibraryDictM){
        [self.adLibraryDictM setValue:adView forKey:placementId];
    }
    
    if (_logEnable) {
        NSLog(@"-->开始请求FBNativeBannerAd广告:%@",placementId);
    }
    
    [self postNotificationWithPlacementId:placementId adPlatform:YGAdPlatformFacebook adType:YGAdTypeBanner adAction:YGAdActionTypeRequest error:nil];
    [adView loadAd];
}


//- (void)requestFBNativeBannerAd:(NSString *)placementId complete:(YGFBNativeBannerAdBlock)completeBlcok {
//
//    if (!_adEnable) {
//        if (_logEnable) {
//            NSLog(@"您已经禁用了广告请求!");
//        }
//
//        if (completeBlcok) {
//            completeBlcok(nil, NO, NO, nil);
//        }
//        return;
//    }
//
//    FBNativeBannerAd *nativeBannerAd = self.adLibraryDictM[placementId];
//    if (nativeBannerAd) {
//        if (completeBlcok) {
//            objc_setAssociatedObject(nativeBannerAd, &kAdCompleteBlockKey, completeBlcok, OBJC_ASSOCIATION_COPY_NONATOMIC);
//        }
//
//        if (nativeBannerAd.isAdValid) {
//            if (_logEnable) {
//                NSLog(@"-->FBNativeBannerAd广告已就绪,可以直接使用:%@",placementId);
//            }
//            if (completeBlcok) {
//                completeBlcok(nativeBannerAd, YES, NO, nil);
//            }
//        }
//        return;
//    }
//
//    nativeBannerAd = [[FBNativeBannerAd alloc] initWithPlacementID:placementId];
//    objc_setAssociatedObject(nativeBannerAd, &kAdCompleteBlockKey, completeBlcok, OBJC_ASSOCIATION_COPY_NONATOMIC);
//    nativeBannerAd.delegate = self;
//    @synchronized(self.adLibraryDictM){
//        [self.adLibraryDictM setValue:nativeBannerAd forKey:placementId];
//    }
//
//    if (_logEnable) {
//        NSLog(@"-->开始请求FBNativeBannerAd广告:%@",placementId);
//    }
//
//    [nativeBannerAd loadAd];
//}

- (void)requestFBInterstitialAd:(NSString *)placementId complete:(YGFBInterstitialAdBlock)completeBlcok {
    
    if (!_adEnable) {
        if (_logEnable) {
            NSLog(@"您已经禁用了广告请求!");
        }
        
        if (completeBlcok) {
            completeBlcok(nil, NO, NO, NO, nil);
        }
        return;
    }
    
    FBInterstitialAd *interstitialAd = self.adLibraryDictM[placementId];
    if (interstitialAd) {
        if (completeBlcok) {
            
            objc_setAssociatedObject(interstitialAd, &kAdCompleteBlockKey, completeBlcok, OBJC_ASSOCIATION_COPY_NONATOMIC);
        }
        if (interstitialAd.isAdValid) {
            if (_logEnable) {
                NSLog(@"-->FBInterstitialAd广告已就绪,可以直接使用:%@",placementId);
            }
            
            if (completeBlcok) {
                completeBlcok(interstitialAd, YES, NO, NO, nil);
            }
        }
        return;
    }
    
    interstitialAd = [[FBInterstitialAd alloc] initWithPlacementID:placementId];
    objc_setAssociatedObject(interstitialAd, &kAdCompleteBlockKey, completeBlcok, OBJC_ASSOCIATION_COPY_NONATOMIC);
    interstitialAd.delegate = self;
    @synchronized(self.adLibraryDictM){
        [self.adLibraryDictM setValue:interstitialAd forKey:placementId];
    }
    
    if (_logEnable) {
        NSLog(@"-->开始请求FBInterstitialAd广告:%@",placementId);
    }
    
    [self postNotificationWithPlacementId:placementId adPlatform:YGAdPlatformFacebook adType:YGAdTypeInterstitial adAction:YGAdActionTypeRequest error:nil];
    [interstitialAd loadAd];
}

- (void)requestFBRewardVideoAd:(NSString *)placementId complete:(YGFBRewardVideoAdBlock)completeBlcok {
    if (!_adEnable) {
        if (_logEnable) {
            NSLog(@"您已经禁用了广告请求!");
        }
        
        if (completeBlcok) {
            completeBlcok(nil, NO, NO, NO, NO, nil);
        }
        return;
    }
    
    FBRewardedVideoAd *rewardedVideoAd = self.adLibraryDictM[placementId];
    if (rewardedVideoAd) {
        if (completeBlcok) {
            objc_setAssociatedObject(rewardedVideoAd, &kAdCompleteBlockKey, completeBlcok, OBJC_ASSOCIATION_COPY_NONATOMIC);
            
        }
        if (rewardedVideoAd.isAdValid) {
            if (_logEnable) {
                NSLog(@"-->FBRewardedVideoAd广告已就绪,可以直接使用:%@",placementId);
            }
            if (completeBlcok) {
                completeBlcok(rewardedVideoAd, YES, NO, NO, NO, nil);
            }
        }
        
        return;
    }
    
    rewardedVideoAd = [[FBRewardedVideoAd alloc] initWithPlacementID:placementId];
    objc_setAssociatedObject(rewardedVideoAd, &kAdCompleteBlockKey, completeBlcok, OBJC_ASSOCIATION_COPY_NONATOMIC);
    rewardedVideoAd.delegate = self;
    @synchronized(self.adLibraryDictM){
        [self.adLibraryDictM setValue:rewardedVideoAd forKey:placementId];
    }
    
    if (_logEnable) {
        NSLog(@"-->开始请求FBRewardedVideoAd广告:%@",placementId);
    }
    
    [self postNotificationWithPlacementId:placementId adPlatform:YGAdPlatformFacebook adType:YGAdTypeReward adAction:YGAdActionTypeRequest error:nil];
    [rewardedVideoAd loadAd];
    
    
}

- (void)requestGADBannerAd:(NSString *)placementId adViewSize:(GADAdSize)size rootViewController:(UIViewController *)rootViewController complete:(YGGADBannerAdBlock)completeBlcok {
    if (!_adEnable) {
        if (_logEnable) {
            NSLog(@"您已经禁用了广告请求!");
        }
        
        if (completeBlcok) {
            completeBlcok(nil, NO, NO, nil);
        }
        return;
    }
    
    GADBannerView *bannerViewAd = self.adLibraryDictM[placementId];
    if (bannerViewAd) {
        if (completeBlcok) {
            objc_setAssociatedObject(bannerViewAd, &kAdCompleteBlockKey, completeBlcok, OBJC_ASSOCIATION_COPY_NONATOMIC);
            
        }
        if (bannerViewAd.isAutoloadEnabled) {
            if (_logEnable) {
                NSLog(@"-->GADBannerView 广告已就绪,可以直接使用:%@",placementId);
            }
            if (completeBlcok) {
                completeBlcok(bannerViewAd, YES, NO, nil);
            }
        }

        return;
    }
    
    bannerViewAd = [[GADBannerView alloc] initWithAdSize:size];
    bannerViewAd.adUnitID = placementId;
    bannerViewAd.delegate = self;
    bannerViewAd.rootViewController = rootViewController;
    GADRequest *request = [GADRequest request];
    request.testDevices = @[kGADSimulatorID];
    
    [self postNotificationWithPlacementId:placementId adPlatform:YGAdPlatformAdMob adType:YGAdTypeBanner adAction:YGAdActionTypeRequest error:nil];
    [bannerViewAd loadRequest:request];
}


- (void)requestGADInterstitialAd:(NSString *)placementId complete:(YGGADInterstitialAdBlock)completeBlcok {
    if (!_adEnable) {
        if (_logEnable) {
            NSLog(@"您已经禁用了广告请求!");
        }
        
        if (completeBlcok) {
            completeBlcok(nil, NO, NO, NO, nil);
        }
        return;
    }
    
    GADInterstitial *interstitialAd = self.adLibraryDictM[placementId];
    if (interstitialAd) {
        if (completeBlcok) {
            objc_setAssociatedObject(interstitialAd, &kAdCompleteBlockKey, completeBlcok, OBJC_ASSOCIATION_COPY_NONATOMIC);
            
        }
        if (interstitialAd.isReady) {
            if (_logEnable) {
                NSLog(@"-->FBInterstitialAd广告已就绪,可以直接使用:%@",placementId);
            }
            
            if (completeBlcok) {
                completeBlcok(interstitialAd, YES, NO, NO, nil);
            }
        }
        return;
    }
    interstitialAd = [[GADInterstitial alloc] initWithAdUnitID:placementId];
    objc_setAssociatedObject(interstitialAd, &kAdCompleteBlockKey, completeBlcok, OBJC_ASSOCIATION_COPY_NONATOMIC);
    interstitialAd.delegate = self;
    @synchronized(self.adLibraryDictM){
        [self.adLibraryDictM setValue:interstitialAd forKey:placementId];
    }
    
    if (_logEnable) {
        NSLog(@"-->开始请求FBInterstitialAd广告:%@",placementId);
    }
    
    GADRequest *request = [GADRequest request];
    request.testDevices = @[kGADSimulatorID];
    
    [self postNotificationWithPlacementId:placementId adPlatform:YGAdPlatformAdMob adType:YGAdTypeInterstitial adAction:YGAdActionTypeRequest error:nil];
    
    [interstitialAd loadRequest:request];
    
}

- (void)requestGADRewardAd:(NSString *)placementId complete:(YGGADRewardAdBlock)completeBlcok {
    
    if (!_adEnable) {
        if (_logEnable) {
            NSLog(@"您已经禁用了广告请求!");
        }
        
        if (completeBlcok) {
            completeBlcok(nil, nil, NO, NO, nil);
        }
        return;
    }
    
    // GADRewardBasedVideoAd 本身是个单例,不采用上面的存储方式
    GADRewardBasedVideoAd *rewardedVideoAd = [GADRewardBasedVideoAd sharedInstance];
    rewardedVideoAd.delegate = self;
    objc_setAssociatedObject(rewardedVideoAd, &kAdCompleteBlockKey, completeBlcok, OBJC_ASSOCIATION_COPY_NONATOMIC);
    
    if (rewardedVideoAd.isReady) {
        
        if (_logEnable) {
            NSLog(@"-->GADRewardBasedVideoAd广告已就绪,可以直接使用:%@",placementId);
        }
        
        if (completeBlcok) {
            completeBlcok(rewardedVideoAd, nil, YES, NO, nil);
        }
        return;
    }
    
    GADRequest *request = [GADRequest request];
    if (self.testDevices.count > 0) {
        
        if (_logEnable) {
            NSLog(@"-->GADRewardBasedVideoAd广告添加测试设备:%@",self.testDevices);
        }
        
        request.testDevices = self.testDevices;
    }
    
    if (_logEnable) {
        NSLog(@"-->开始请求GADRewardBasedVideoAd广告:%@",placementId);
    }
    
    [self postNotificationWithPlacementId:placementId adPlatform:YGAdPlatformAdMob adType:YGAdTypeReward adAction:YGAdActionTypeRequest error:nil];
    [rewardedVideoAd loadRequest:request withAdUnitID:placementId];
}



#pragma mark - FBNativeAdDelegate
/**
 Sent when an FBNativeAd has been successfully loaded.
 */
- (void)nativeAdDidLoad:(FBNativeAd *)nativeAd {
    
    [self postNotificationWithPlacementId:nativeAd.placementID adPlatform:YGAdPlatformFacebook adType:YGAdTypeNative adAction:YGAdActionTypeSuccess error:nil];
    
    if (_logEnable) {
        NSLog(@"-->FBNativeAd广告请求成功:%@",nativeAd.placementID);
    }
    
    YGFBNativeAdBlock block = objc_getAssociatedObject(nativeAd, &kAdCompleteBlockKey);
    if (block) {
        block(nativeAd, YES, NO, nil);
    }
}

/**
 Sent when an FBNativeAd is failed to load.
 */
- (void)nativeAd:(FBNativeAd *)nativeAd didFailWithError:(NSError *)error {
    
    [self postNotificationWithPlacementId:nativeAd.placementID adPlatform:YGAdPlatformFacebook adType:YGAdTypeNative adAction:YGAdActionTypeFailed error:error];
    
    if (_logEnable) {
        NSLog(@"-->FBNativeAd广告请求失败:%@\nErrorInfo:%@",nativeAd.placementID, error.localizedDescription);
    }
    
    YGFBNativeAdBlock block = objc_getAssociatedObject(nativeAd, &kAdCompleteBlockKey);
    if (block) {
        block(nativeAd, NO, NO, error);
    }
    [self removeAdObjectWithPlacementID:nativeAd.placementID];
}

/**
 Sent after an ad has been clicked by the person.
 */
- (void)nativeAdDidClick:(FBNativeAd *)nativeAd {
    
    [self postNotificationWithPlacementId:nativeAd.placementID adPlatform:YGAdPlatformFacebook adType:YGAdTypeNative adAction:YGAdActionTypeClick error:nil];
    
    if (_logEnable) {
        NSLog(@"-->FBNativeAd广告点击:%@",nativeAd.placementID);
    }
    
    YGFBNativeAdBlock block = objc_getAssociatedObject(nativeAd, &kAdCompleteBlockKey);
    if (block) {
        block(nativeAd, NO, YES, nil);
    }
}

/**
 Sent when an FBNativeAd has succesfully downloaded all media
 */
- (void)nativeAdDidDownloadMedia:(FBNativeAd *)nativeAd {
    
}

/**
 Sent immediately before the impression of an FBNativeAd object will be logged.
 */
- (void)nativeAdWillLogImpression:(FBNativeAd *)nativeAd {
    
}

/**
 When an ad is clicked, the modal view will be presented. And when the user finishes the
 interaction with the modal view and dismiss it, this message will be sent, returning control
 to the application.
 */
- (void)nativeAdDidFinishHandlingClick:(FBNativeAd *)nativeAd {
    
}

#pragma mark - FBAdViewDelegate
/**
 Sent after an ad has been clicked by the person.
 
 - Parameter adView: An FBAdView object sending the message.
 */
- (void)adViewDidClick:(FBAdView *)adView {
    
    [self postNotificationWithPlacementId:adView.placementID adPlatform:YGAdPlatformFacebook adType:YGAdTypeBanner adAction:YGAdActionTypeClick error:nil];
    
    if (_logEnable) {
        NSLog(@"-->FBNativeAd广告点击:%@",adView.placementID);
    }
    
    YGFBBannerAdBlock block = objc_getAssociatedObject(adView, &kAdCompleteBlockKey);
    if (block) {
        block(adView, NO, YES, nil);
    }
}
/**
 When an ad is clicked, the modal view will be presented. And when the user finishes the
 interaction with the modal view and dismiss it, this message will be sent, returning control
 to the application.
 
 - Parameter adView: An FBAdView object sending the message.
 */
- (void)adViewDidFinishHandlingClick:(FBAdView *)adView {
    
}
/**
 Sent when an ad has been successfully loaded.
 
 - Parameter adView: An FBAdView object sending the message.
 */
- (void)adViewDidLoad:(FBAdView *)adView {
    [self postNotificationWithPlacementId:adView.placementID adPlatform:YGAdPlatformFacebook adType:YGAdTypeBanner adAction:YGAdActionTypeSuccess error:nil];
    
    if (_logEnable) {
        NSLog(@"-->FBNativeAd广告请求成功:%@",adView.placementID);
    }
    
    YGFBBannerAdBlock block = objc_getAssociatedObject(adView, &kAdCompleteBlockKey);
    if (block) {
        block(adView, YES, NO, nil);
    }
}
/**
 Sent after an FBAdView fails to load the ad.
 
 - Parameter adView: An FBAdView object sending the message.
 - Parameter error: An error object containing details of the error.
 */
- (void)adView:(FBAdView *)adView didFailWithError:(NSError *)error {
    [self postNotificationWithPlacementId:adView.placementID adPlatform:YGAdPlatformFacebook adType:YGAdTypeBanner adAction:YGAdActionTypeFailed error:error];
    
    if (_logEnable) {
        NSLog(@"-->FBNativeAd广告请求失败:%@\nErrorInfo:%@",adView.placementID, error.localizedDescription);
    }
    
    YGFBBannerAdBlock block = objc_getAssociatedObject(adView, &kAdCompleteBlockKey);
    if (block) {
        block(adView, NO, NO, error);
    }
    [self removeAdObjectWithPlacementID:adView.placementID];
}

/**
 Sent immediately before the impression of an FBAdView object will be logged.
 
 - Parameter adView: An FBAdView object sending the message.
 */
- (void)adViewWillLogImpression:(FBAdView *)adView {
    
}


//#pragma mark - FBNativeBannerAdDelegate
///**
// * Sent when an FBNativeBannerAd has been successfully loaded.
// */
//- (void)nativeBannerAdDidLoad:(FBNativeBannerAd *)nativeBannerAd {
//    if (_logEnable) {
//        NSLog(@"-->FBNativeBannerAd广告请求成功:%@",nativeBannerAd.placementID);
//    }
//
//    YGFBNativeBannerAdBlock block = objc_getAssociatedObject(nativeBannerAd, &kAdCompleteBlockKey);
//    if (block) {
//        block(nativeBannerAd, YES, NO, nil);
//    }
//}
//
//
///**
// * Sent when an FBNativeBannerAd is failed to load.
// */
//- (void)nativeBannerAd:(FBNativeBannerAd *)nativeBannerAd didFailWithError:(NSError *)error {
//    if (_logEnable) {
//        NSLog(@"-->FBNativeBannerAd广告请求失败:%@\nErrorInfo:%@",nativeBannerAd.placementID, error.localizedDescription);
//    }
//
//    YGFBNativeBannerAdBlock block = objc_getAssociatedObject(nativeBannerAd, &kAdCompleteBlockKey);
//    if (block) {
//        block(nativeBannerAd, NO, NO, error);
//    }
//    [self removeAdObjectWithPlacementID:nativeBannerAd.placementID];
//}
//
///**
// * Sent after an ad has been clicked by the person.
// */
//- (void)nativeBannerAdDidClick:(FBNativeBannerAd *)nativeBannerAd {
//    if (_logEnable) {
//        NSLog(@"-->FBNativeBannerAd广告点击:%@",nativeBannerAd.placementID);
//    }
//
//    YGFBNativeBannerAdBlock block = objc_getAssociatedObject(nativeBannerAd, &kAdCompleteBlockKey);
//    if (block) {
//        block(nativeBannerAd, NO, YES, nil);
//    }
//}
//
///**
// * Sent when an FBNativeBannerAd has succesfully downloaded all media
// */
//- (void)nativeBannerAdDidDownloadMedia:(FBNativeBannerAd *)nativeBannerAd {
//
//}
//
///**
// * Sent immediately before the impression of an FBNativeBannerAd object will be logged.
// */
//- (void)nativeBannerAdWillLogImpression:(FBNativeBannerAd *)nativeBannerAd {
//
//}
//
///**
// * When an ad is clicked, the modal view will be presented. And when the user finishes the
// * interaction with the modal view and dismiss it, this message will be sent, returning control
// * to the application.
// */
//- (void)nativeBannerAdDidFinishHandlingClick:(FBNativeBannerAd *)nativeBannerAd {
//
//}



#pragma mark - FBInterstitialAdDelegate
/**
 * Sent when an FBInterstitialAd successfully loads an ad.
 */
- (void)interstitialAdDidLoad:(FBInterstitialAd *)interstitialAd {
    [self postNotificationWithPlacementId:interstitialAd.placementID adPlatform:YGAdPlatformFacebook adType:YGAdTypeInterstitial adAction:YGAdActionTypeSuccess error:nil];
    
    if (_logEnable) {
        NSLog(@"-->FBInterstitialAd:广告请求成功:%@",interstitialAd.placementID);
    }
    
    YGFBInterstitialAdBlock block = objc_getAssociatedObject(interstitialAd, &kAdCompleteBlockKey);
    if (block) {
        block(interstitialAd, YES, NO, NO, nil);
    }
}

/**
 * Sent when an FBInterstitialAd failes to load an ad.
 */
- (void)interstitialAd:(FBInterstitialAd *)interstitialAd didFailWithError:(NSError *)error {
    [self postNotificationWithPlacementId:interstitialAd.placementID adPlatform:YGAdPlatformFacebook adType:YGAdTypeInterstitial adAction:YGAdActionTypeFailed error:error];
    
    if (_logEnable) {
        NSLog(@"-->FBInterstitialAd:广告请求失败:%@\nErrorInfo:%@",interstitialAd.placementID, error.localizedDescription);
    }
    
    YGFBInterstitialAdBlock block = objc_getAssociatedObject(interstitialAd, &kAdCompleteBlockKey);
    if (block) {
        block(interstitialAd, NO, NO, NO, error);
    }
    [self.adLibraryDictM removeObjectForKey:interstitialAd.placementID];
}

/**
 * Sent after an ad in the FBInterstitialAd object is clicked. The appropriate app store view or
 * app browser will be launched.
 */
- (void)interstitialAdDidClick:(FBInterstitialAd *)interstitialAd {
    [self postNotificationWithPlacementId:interstitialAd.placementID adPlatform:YGAdPlatformFacebook adType:YGAdTypeInterstitial adAction:YGAdActionTypeClick error:nil];
    
    if (_logEnable) {
        NSLog(@"-->FBInterstitialAd:广告点击:%@",interstitialAd.placementID);
    }
    
    YGFBInterstitialAdBlock block = objc_getAssociatedObject(interstitialAd, &kAdCompleteBlockKey);
    if (block) {
        block(interstitialAd, NO, YES, NO, nil);
    }
}

/**
 * Sent immediately before an FBInterstitialAd object will be dismissed from the screen.
 */
- (void)interstitialAdWillClose:(FBInterstitialAd *)interstitialAd {
    
}

/**
 * Sent after an FBInterstitialAd object has been dismissed from the screen, returning control
 * to your application.
 */
- (void)interstitialAdDidClose:(FBInterstitialAd *)interstitialAd {
    [self postNotificationWithPlacementId:interstitialAd.placementID adPlatform:YGAdPlatformFacebook adType:YGAdTypeInterstitial adAction:YGAdActionTypeClose error:nil];
    
    if (_logEnable) {
        NSLog(@"-->FBInterstitialAd:广告关闭:%@",interstitialAd.placementID);
    }
    
    YGFBInterstitialAdBlock block = objc_getAssociatedObject(interstitialAd, &kAdCompleteBlockKey);
    if (block) {
        block(interstitialAd, NO, NO, YES, nil);
    }
    
    [self.adLibraryDictM removeObjectForKey:interstitialAd.placementID];
}

/**
 * Sent immediately before the impression of an FBInterstitialAd object will be logged.
 */
- (void)interstitialAdWillLogImpression:(FBInterstitialAd *)interstitialAd {
    
}

#pragma mark - FBRewardedVideoAdDelegate
/**
 Sent after an ad has been clicked by the person.
 
 - Parameter rewardedVideoAd: An FBRewardedVideoAd object sending the message.
 */
- (void)rewardedVideoAdDidClick:(FBRewardedVideoAd *)rewardedVideoAd {
    [self postNotificationWithPlacementId:rewardedVideoAd.placementID adPlatform:YGAdPlatformFacebook adType:YGAdTypeReward adAction:YGAdActionTypeClick error:nil];
    
    if (_logEnable) {
        NSLog(@"-->FBRewardedVideoAd:广告点击:%@",rewardedVideoAd.placementID);
    }
    YGFBRewardVideoAdBlock block = objc_getAssociatedObject(rewardedVideoAd, &kAdCompleteBlockKey);
    if (block) {
        block(rewardedVideoAd, NO, YES, NO, NO, nil);
    }
}

/**
 Sent when an ad has been successfully loaded.
 
 - Parameter rewardedVideoAd: An FBRewardedVideoAd object sending the message.
 */
- (void)rewardedVideoAdDidLoad:(FBRewardedVideoAd *)rewardedVideoAd {
    [self postNotificationWithPlacementId:rewardedVideoAd.placementID adPlatform:YGAdPlatformFacebook adType:YGAdTypeReward adAction:YGAdActionTypeSuccess error:nil];
    if (_logEnable) {
        NSLog(@"-->FBRewardedVideoAd:广告加载完成:%@",rewardedVideoAd.placementID);
    }
    YGFBRewardVideoAdBlock block = objc_getAssociatedObject(rewardedVideoAd, &kAdCompleteBlockKey);
    if (block) {
        block(rewardedVideoAd, YES, NO, NO, NO, nil);
    }
}

/**
 Sent after an FBRewardedVideoAd object has been dismissed from the screen, returning control
 to your application.
 
 - Parameter rewardedVideoAd: An FBRewardedVideoAd object sending the message.
 */
- (void)rewardedVideoAdDidClose:(FBRewardedVideoAd *)rewardedVideoAd {
    [self postNotificationWithPlacementId:rewardedVideoAd.placementID adPlatform:YGAdPlatformFacebook adType:YGAdTypeReward adAction:YGAdActionTypeClose error:nil];
    if (_logEnable) {
        NSLog(@"-->FBRewardedVideoAd:广告关闭:%@",rewardedVideoAd.placementID);
    }
    YGFBRewardVideoAdBlock block = objc_getAssociatedObject(rewardedVideoAd, &kAdCompleteBlockKey);
    if (block) {
        block(rewardedVideoAd, NO, NO, YES, NO, nil);
    }
}

/**
 Sent immediately before an FBRewardedVideoAd object will be dismissed from the screen.
 
 - Parameter rewardedVideoAd: An FBRewardedVideoAd object sending the message.
 */
- (void)rewardedVideoAdWillClose:(FBRewardedVideoAd *)rewardedVideoAd {
    if (_logEnable) {
        NSLog(@"-->FBRewardedVideoAd:广告将要关闭:%@",rewardedVideoAd.placementID);
    }
}

/**
 Sent after an FBRewardedVideoAd fails to load the ad.
 
 - Parameter rewardedVideoAd: An FBRewardedVideoAd object sending the message.
 - Parameter error: An error object containing details of the error.
 */
- (void)rewardedVideoAd:(FBRewardedVideoAd *)rewardedVideoAd didFailWithError:(NSError *)error {
    
    [self postNotificationWithPlacementId:rewardedVideoAd.placementID adPlatform:YGAdPlatformFacebook adType:YGAdTypeReward adAction:YGAdActionTypeFailed error:error];
    
    if (_logEnable) {
        NSLog(@"-->FBRewardedVideoAd:广告加载失败:%@\nErrorInfo:%@",rewardedVideoAd.placementID, error.localizedDescription);
    }
    YGFBRewardVideoAdBlock block = objc_getAssociatedObject(rewardedVideoAd, &kAdCompleteBlockKey);
    if (block) {
        block(rewardedVideoAd, NO, NO, NO, NO, error);
    }
    [self removeAdObjectWithPlacementID:rewardedVideoAd.placementID];
}

/**
 Sent after the FBRewardedVideoAd object has finished playing the video successfully.
 Reward the user on this callback.
 
 - Parameter rewardedVideoAd: An FBRewardedVideoAd object sending the message.
 */
- (void)rewardedVideoAdVideoComplete:(FBRewardedVideoAd *)rewardedVideoAd {
    if (_logEnable) {
        NSLog(@"-->FBRewardedVideoAd:广告播放完成:%@",rewardedVideoAd.placementID);
    }

}

/**
 Sent immediately before the impression of an FBRewardedVideoAd object will be logged.
 
 - Parameter rewardedVideoAd: An FBRewardedVideoAd object sending the message.
 */
- (void)rewardedVideoAdWillLogImpression:(FBRewardedVideoAd *)rewardedVideoAd {
    
}

/**
 Sent if server call to publisher's reward endpoint returned HTTP status code 200.
 
 - Parameter rewardedVideoAd: An FBRewardedVideoAd object sending the message.
 */
- (void)rewardedVideoAdServerRewardDidSucceed:(FBRewardedVideoAd *)rewardedVideoAd {
    if (_logEnable) {
        NSLog(@"-->FBRewardedVideoAd:广告奖励获取成功:%@",rewardedVideoAd.placementID);
    }
    YGFBRewardVideoAdBlock block = objc_getAssociatedObject(rewardedVideoAd, &kAdCompleteBlockKey);
    if (block) {
        block(rewardedVideoAd, NO, NO, NO, YES, nil);
    }
}

/**
 Sent if server call to publisher's reward endpoint did not return HTTP status code 200
 or if the endpoint timed out.
 
 - Parameter rewardedVideoAd: An FBRewardedVideoAd object sending the message.
 */
- (void)rewardedVideoAdServerRewardDidFail:(FBRewardedVideoAd *)rewardedVideoAd {
    if (_logEnable) {
        NSLog(@"-->FBRewardedVideoAd:广告奖励获取失败:%@",rewardedVideoAd.placementID);
    }
    YGFBRewardVideoAdBlock block = objc_getAssociatedObject(rewardedVideoAd, &kAdCompleteBlockKey);
    if (block) {
        block(rewardedVideoAd, NO, NO, NO, NO, nil);
    }
}

#pragma mark - GADBannerViewDelegate
/// Tells the delegate that an ad request successfully received an ad. The delegate may want to add
/// the banner view to the view hierarchy if it hasn't been added yet.
- (void)adViewDidReceiveAd:(GADBannerView *)bannerView {
    
    [self postNotificationWithPlacementId:bannerView.adUnitID adPlatform:YGAdPlatformAdMob adType:YGAdTypeBanner adAction:YGAdActionTypeSuccess error:nil];
    
    if (_logEnable) {
        NSLog(@"-->GADBannerView:广告加载完成:%@",bannerView.adUnitID);
    }
    YGGADBannerAdBlock block = objc_getAssociatedObject(bannerView, &kAdCompleteBlockKey);
    if (block) {
        block(bannerView, YES, NO, nil);
    }
}

/// Tells the delegate that an ad request failed. The failure is normally due to network
/// connectivity or ad availablility (i.e., no fill).
- (void)adView:(GADBannerView *)bannerView didFailToReceiveAdWithError:(GADRequestError *)error {
    
    [self postNotificationWithPlacementId:bannerView.adUnitID adPlatform:YGAdPlatformAdMob adType:YGAdTypeBanner adAction:YGAdActionTypeFailed error:error];
    
    if (_logEnable) {
        NSLog(@"-->GADBannerView:广告加载失败:%@",bannerView.adUnitID);
    }
    YGGADBannerAdBlock block = objc_getAssociatedObject(bannerView, &kAdCompleteBlockKey);
    if (block) {
        block(bannerView, NO, NO, error);
    }
    [self removeAdObjectWithPlacementID:bannerView.adUnitID];
}


/// Tells the delegate that a full screen view will be presented in response to the user clicking on
/// an ad. The delegate may want to pause animations and time sensitive interactions.
- (void)adViewWillPresentScreen:(GADBannerView *)bannerView {
    
    if (_logEnable) {
        NSLog(@"-->GADBannerView:广告点击:%@",bannerView.adUnitID);
    }
    YGGADBannerAdBlock block = objc_getAssociatedObject(bannerView, &kAdCompleteBlockKey);
    if (block) {
        block(bannerView, NO, YES, nil);
    }
}

/// Tells the delegate that the full screen view will be dismissed.
- (void)adViewWillDismissScreen:(GADBannerView *)bannerView {
    
}

/// Tells the delegate that the full screen view has been dismissed. The delegate should restart
/// anything paused while handling adViewWillPresentScreen:.
- (void)adViewDidDismissScreen:(GADBannerView *)bannerView {
    
}

/// Tells the delegate that the user click will open another app, backgrounding the current
/// application. The standard UIApplicationDelegate methods, like applicationDidEnterBackground:,
/// are called immediately before this method is called.
- (void)adViewWillLeaveApplication:(GADBannerView *)bannerView {
    
}


#pragma mark - GADInterstitialDelegate
/// Called when an interstitial ad request succeeded. Show it at the next transition point in your
/// application such as when transitioning between view controllers.
- (void)interstitialDidReceiveAd:(GADInterstitial *)ad {
    
    [self postNotificationWithPlacementId:ad.adUnitID adPlatform:YGAdPlatformAdMob adType:YGAdTypeInterstitial adAction:YGAdActionTypeSuccess error:nil];
    
    if (_logEnable) {
        NSLog(@"-->GADInterstitial:广告加载完成:%@",ad.adUnitID);
    }
    YGGADInterstitialAdBlock block = objc_getAssociatedObject(ad, &kAdCompleteBlockKey);
    if (block) {
        block(ad, YES, NO, NO, nil);
    }
}

/// Called when an interstitial ad request completed without an interstitial to
/// show. This is common since interstitials are shown sparingly to users.
- (void)interstitial:(GADInterstitial *)ad didFailToReceiveAdWithError:(GADRequestError *)error {
    
    [self postNotificationWithPlacementId:ad.adUnitID adPlatform:YGAdPlatformAdMob adType:YGAdTypeInterstitial adAction:YGAdActionTypeFailed error:error];
    
    if (_logEnable) {
        NSLog(@"-->GADInterstitial:广告加载失败:%@\nErrorInfo:%@",ad.adUnitID, error.localizedDescription);
    }
    YGGADInterstitialAdBlock block = objc_getAssociatedObject(ad, &kAdCompleteBlockKey);
    if (block) {
        block(ad, NO, NO, NO, error);
    }
    [self removeAdObjectWithPlacementID:ad.adUnitID];
}

/// Called just before presenting an interstitial. After this method finishes the interstitial will
/// animate onto the screen. Use this opportunity to stop animations and save the state of your
/// application in case the user leaves while the interstitial is on screen (e.g. to visit the App
/// Store from a link on the interstitial).
- (void)interstitialWillPresentScreen:(GADInterstitial *)ad {
    [self postNotificationWithPlacementId:ad.adUnitID adPlatform:YGAdPlatformAdMob adType:YGAdTypeInterstitial adAction:YGAdActionTypeClick error:nil];
    
    if (_logEnable) {
        NSLog(@"-->GADInterstitial:广告展示:%@",ad.adUnitID);
    }
    YGGADInterstitialAdBlock block = objc_getAssociatedObject(ad, &kAdCompleteBlockKey);
    if (block) {
        block(ad, NO, YES, NO, nil);
    }
}

/// Called when |ad| fails to present.
- (void)interstitialDidFailToPresentScreen:(GADInterstitial *)ad {
    
}

/// Called before the interstitial is to be animated off the screen.
- (void)interstitialWillDismissScreen:(GADInterstitial *)ad {
    
}

/// Called just after dismissing an interstitial and it has animated off the screen.
- (void)interstitialDidDismissScreen:(GADInterstitial *)ad {
    
    [self postNotificationWithPlacementId:ad.adUnitID adPlatform:YGAdPlatformAdMob adType:YGAdTypeInterstitial adAction:YGAdActionTypeClose error:nil];
    
    if (_logEnable) {
        NSLog(@"-->GADInterstitial:广告关闭:%@",ad.adUnitID);
    }
    YGGADInterstitialAdBlock block = objc_getAssociatedObject(ad, &kAdCompleteBlockKey);
    if (block) {
        block(ad, NO, NO, YES, nil);
    }
}

/// Called just before the application will background or terminate because the user clicked on an
/// ad that will launch another application (such as the App Store). The normal
/// UIApplicationDelegate methods, like applicationDidEnterBackground:, will be called immediately
/// before this.
- (void)interstitialWillLeaveApplication:(GADInterstitial *)ad {
    
}



#pragma mark - GADRewardBasedVideoAdDelegate
/**
 * Tells the delegate that the reward based video ad has rewarded the user.
 */
- (void)rewardBasedVideoAd:(GADRewardBasedVideoAd *)rewardBasedVideoAd
   didRewardUserWithReward:(GADAdReward *)reward {
    

    
    if (_logEnable) {
        NSLog(@"-->GADRewardBasedVideoAd:可获得奖励");
    }
    
    YGGADRewardAdBlock block = objc_getAssociatedObject(rewardBasedVideoAd, &kAdCompleteBlockKey);
    if (block) {
        block(rewardBasedVideoAd, reward, NO, NO, nil);
    }
}

/**
 * Tells the delegate that a reward based video ad was received.
 */
- (void)rewardBasedVideoAdDidReceiveAd:(GADRewardBasedVideoAd *)rewardBasedVideoAd {
    
    if (_logEnable) {
        NSLog(@"-->GADRewardBasedVideoAd:广告请求成功");
    }
    
    YGGADRewardAdBlock block = objc_getAssociatedObject(rewardBasedVideoAd, &kAdCompleteBlockKey);
    if (block) {
        block(rewardBasedVideoAd, nil, YES, NO, nil);
    }
}

/**
 * Tells the delegate that the reward based video ad failed to load.
 */
- (void)rewardBasedVideoAd:(GADRewardBasedVideoAd *)rewardBasedVideoAd
    didFailToLoadWithError:(NSError *)error {
    
    if (_logEnable) {
        NSLog(@"-->GADRewardBasedVideoAd:广告请求失败:ErrorInfo:%@", error.localizedDescription);
    }
    
    YGGADRewardAdBlock block = objc_getAssociatedObject(rewardBasedVideoAd, &kAdCompleteBlockKey);
    if (block) {
        block(rewardBasedVideoAd, nil, NO, NO, error);
    }
}

/**
 * Tells the delegate that the reward based video ad closed.
 */
- (void)rewardBasedVideoAdDidClose:(GADRewardBasedVideoAd *)rewardBased {
    
    if (_logEnable) {
        NSLog(@"-->GADRewardBasedVideoAd:广告关闭");
    }
    
    YGGADRewardAdBlock block = objc_getAssociatedObject(rewardBased, &kAdCompleteBlockKey);
    if (block) {
        block(rewardBased, nil, NO, YES, nil);
    }
}

/**
 * Tells the delegate that the reward based video ad opened.
 */
- (void)rewardBasedVideoAdDidOpen:(GADRewardBasedVideoAd *)rewardBased {
    if (_logEnable) {
        NSLog(@"-->GADRewardBasedVideoAd did opened");
    }
}

/**
 * Tells the delegate that the reward based video ad started playing.
 */
- (void)rewardBasedVideoAdDidStartPlaying:(GADRewardBasedVideoAd *)rewardBased {
    if (_logEnable) {
        NSLog(@"-->GADRewardBasedVideoAd did started playing");
    }
}

/**
 * Tells the delegate that the reward based video ad completed playing.
 */
- (void)rewardBasedVideoAdDidCompletePlaying:(GADRewardBasedVideoAd *)rewardBased {
    if (_logEnable) {
        NSLog(@"-->GADRewardBasedVideoAd completed playing");
    }
}

/**
 * Tells the delegate that the reward based video ad will leave the application.
 */
- (void)rewardBasedVideoAdWillLeaveApplication:(GADRewardBasedVideoAd *)rewardBased {
    if (_logEnable) {
        NSLog(@"-->GADRewardBasedVideoAd will leave the application");
    }
}

@end
